﻿using AutoMapper;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using Rj_GsInsurance.Server.DataBaseContext;
using Rj_GsInsurance.Server.DataBaseContext.Entities;
using Rj_GsInsurance.Server.Models;
using Rj_GsInsurance.Server.Services;
using System.Collections.ObjectModel;
using System.Data;
using System.Windows;
using Wpf.Ui;
using Wpf.Ui.Controls;
using Wpf.Ui.Extensions;

namespace Rj_GsInsurance.Client.ViewModels
{
    public partial class InsurCatalogueManageViewModel : ObservableObject
    {
        [ObservableProperty]
        private List<InsurTypeCode> _CatalogueTypeCoding = InsurDict.CatalogueTypeCoding;

        [ObservableProperty]
        private string _CatalogueType = string.Empty;

        private string _autoSearchInsurText = string.Empty;
        public string AutoSearchInsurText
        {
            get => _autoSearchInsurText;
            set
            {
                _ = SetProperty(ref _autoSearchInsurText, value);
                OnSearchInsur(value);
            }
        }
        private string _autoSearchHisText = string.Empty;
        public string AutoSearchHisText
        {
            get => _autoSearchHisText;
            set
            {
                _ = SetProperty(ref _autoSearchHisText, value);
                OnSearchHis(value);
            }
        }

        [ObservableProperty]
        private ObservableCollection<object> _selectInsurData;
        [ObservableProperty]
        private object _selectedInsurData;
        [ObservableProperty]
        private ObservableCollection<SystemTbPubItem> _selectHisData;
        private SystemTbPubItem _selectedHisData;
        public SystemTbPubItem SelectedHisData
        {
            get => _selectedHisData;
            set
            {
                _ = SetProperty(ref _selectedHisData, value);
                if (value != null)
                {
                    AutoSearchInsurText = value.ItemName!;
                }
            }
        }
        [ObservableProperty]
        private bool _insurPageUpIsEnabled = false;
        [ObservableProperty]
        private bool _insurPageDownIsEnabled = false;
        [ObservableProperty]
        private int _insurCurrentPage;
        [ObservableProperty]
        private int _insurPageCount;
        [ObservableProperty]
        private bool _hisPageUpIsEnabled = false;
        [ObservableProperty]
        private bool _hisPageDownIsEnabled = false;
        [ObservableProperty]
        private int _hisCurrentPage;
        [ObservableProperty]
        private int _hisPageCount;

        private int PageSize = 50;
        [ObservableProperty]
        private string _InsurCode = string.Empty;
        [ObservableProperty]
        private Dictionary<string, string> _HisItemDetailsDict;        
        [ObservableProperty]
        private Visibility _DetailsVisibility=Visibility.Collapsed;

        private ObservableCollection<object> _allInsurData;
        private ObservableCollection<SystemTbPubItem> _allHisData;

        private bool _queryAll = false;
        public bool QueryAll
        {
            get => _queryAll;
            set
            {
                _ = SetProperty(ref _queryAll, value);
                if (value)
                    OnQuery(nameof(QueryAll));
            }
        }
        private bool _queryNo = true;
        public bool QueryNo
        {
            get => _queryNo;
            set
            {
                _ = SetProperty(ref _queryNo, value);
                if (value)
                    OnQuery(nameof(QueryNo));
            }
        }
        private bool _queryYes = false;
        public bool QueryYes
        {
            get => _queryYes;
            set
            {
                _ = SetProperty(ref _queryYes, value);
                if (value)
                    OnQuery(nameof(QueryYes));
            }
        }

        private IGsInsuranceServer GsInsuranceServer;

        public ISnackbarService SnackbarService { get; set; }
        public IContentDialogService ContentDialogService { get; set; }

        private HisDbContext HisDbContext;
        private IMapper Mapper;

        public InsurCatalogueManageViewModel(IGsInsuranceServer gsInsuranceServer, ISnackbarService snackbarService, HisDbContext hisDbContext, IMapper mapper, IContentDialogService contentDialogService)
        {
            GsInsuranceServer = gsInsuranceServer;
            SnackbarService = snackbarService;
            HisDbContext = hisDbContext;
            Mapper = mapper;
            ContentDialogService = contentDialogService;
        }

        private void UpdateSearchResults(string value)
        {
            _ = Task.Run(() =>
            {
                if (string.IsNullOrWhiteSpace(value))
                    return true;
                return true;
            });
        }
        [RelayCommand]
        private async Task OnQuery(object param)
        {
            var checkValue=param as string;
            if(checkValue== "QueryAll")
            {
                QueryYes=false;
                QueryNo=false;
            }
            if (checkValue == "QueryYes")
            {
                QueryAll = false;
                QueryNo = false;
            }
            if (checkValue == "QueryNo")
            {
                QueryYes = false;
                QueryAll = false;
            }
            if (string.IsNullOrWhiteSpace(CatalogueType))
            {
                SnackbarService.Show(
                    "警告!",
                    $"请选择目录类型",
                    ControlAppearance.Danger,
                    new SymbolIcon(SymbolRegular.Fluent24),
                    TimeSpan.FromSeconds(30)
                );
                return;
            }
            HisCurrentPage = 1;
            InsurCurrentPage = 1;
            if (QueryAll)
            {
                List<SystemTbPubItem> pubItems = default;
                if (CatalogueType == "01")
                {
                    pubItems = await HisDbContext.SystemTbPubItems.Where(w => w.ItemCategory == 12 || w.ItemCategory == 13 || w.ItemCategory == 14 || w.ItemCategory == 15).ToListAsync();
                }
                else if (CatalogueType == "02")
                {
                    pubItems = await HisDbContext.SystemTbPubItems.Where(w => w.ItemCategory == 12 && w.ItemCategory != 13 && w.ItemCategory != 14 && w.ItemCategory != 15).ToListAsync();
                }
                _allHisData = new ObservableCollection<SystemTbPubItem>(pubItems);
            }
            else if (QueryYes)
            {
                List<SystemTbPubItem> pubItems = default;
                if (CatalogueType == "01")
                {
                    pubItems = await HisDbContext.SystemTbPubItems.Where(w => !string.IsNullOrWhiteSpace(w.InsurGsCode) && (w.ItemCategory == 12 || w.ItemCategory == 13 || w.ItemCategory == 14 || w.ItemCategory == 15)).ToListAsync();
                }
                else if (CatalogueType == "02")
                {
                    pubItems = await HisDbContext.SystemTbPubItems.Where(w => w.ItemCategory != 12 && w.ItemCategory != 13 && w.ItemCategory != 14 && w.ItemCategory != 15 && !string.IsNullOrWhiteSpace(w.InsurGsCode)).ToListAsync();
                }
                _allHisData = new ObservableCollection<SystemTbPubItem>(pubItems);
            }
            else if (QueryNo)
            {
                List<SystemTbPubItem> pubItems = default;
                if (CatalogueType == "01")
                {
                    pubItems = await HisDbContext.SystemTbPubItems.Where(w => string.IsNullOrWhiteSpace(w.InsurGsCode) && (w.ItemCategory == 12 || w.ItemCategory == 13 || w.ItemCategory == 14 || w.ItemCategory == 15)).ToListAsync();
                }
                else if (CatalogueType == "02")
                {
                    pubItems = await HisDbContext.SystemTbPubItems.Where(w => string.IsNullOrWhiteSpace(w.InsurGsCode) && w.ItemCategory != 12 && w.ItemCategory != 13 && w.ItemCategory != 14 && w.ItemCategory != 15).ToListAsync();
                }
                _allHisData = new ObservableCollection<SystemTbPubItem>(pubItems);
            }
            if (CatalogueType == "01")
            {
                _allInsurData = new ObservableCollection<object>(await HisDbContext.InsurWorkInjuryCatalogueDrugs.Take(1000).ToListAsync());
            }
            else if (CatalogueType == "02")
            {
                _allInsurData = new ObservableCollection<object>(await HisDbContext.InsurWorkInjuryCatalogueTreatmentItems.Take(1000).ToListAsync());
            }
            AutoSearchHisText = string.Empty;
            AutoSearchInsurText = string.Empty;
            if (_allHisData != null && _allHisData.Count > 0)
            {
                HisCurrentPage = 1;
            }
            if (_allInsurData != null && _allInsurData.Count > 0)
            {
                InsurCurrentPage = 1;
            }
            CalculatePage();
        }
        [RelayCommand]
        private async Task OnSearchInsur(object param)
        {
            string value = param as string;
            if (string.IsNullOrWhiteSpace(value))
            {
                InsurCurrentPage = 1;
                CalculatePageInsur();
                return;
            }
            if (CatalogueType == "01")
            {
                var data = await HisDbContext.InsurWorkInjuryCatalogueDrugs.Where(obj => obj.DrugCode == value || obj.ChineseName.Contains(value)).Take(1000).ToListAsync();
                SelectInsurData = new ObservableCollection<object>(data);
            }
            else if (CatalogueType == "02")
            {
                var data = await HisDbContext.InsurWorkInjuryCatalogueTreatmentItems.Where(obj => obj.ItemCode == value || obj.ItemName.Contains(value)).Take(1000).ToListAsync();
                SelectInsurData = new ObservableCollection<object>(data);
            }
        }
        [RelayCommand]
        private async Task OnSearchHis(object param)
        {
            string value = param as string;
            if (string.IsNullOrWhiteSpace(value))
            {
                HisCurrentPage = 1;
                CalculatePageHis();
                return;
            }
            if (CatalogueType == "01")
            {
                var systemTbPubItems = await HisDbContext.SystemTbPubItems.Where(w => (w.ItemCategory == 12 || w.ItemCategory == 13 || w.ItemCategory == 14 || w.ItemCategory == 15) && w.ItemCode.ToString() == value || (w.ItemName != null && w.ItemName.Contains(value)) || w.StandCode == value || w.NationCode == value).ToListAsync();
                SelectHisData = new ObservableCollection<SystemTbPubItem>(systemTbPubItems);
            }
            else if (CatalogueType == "02")
            {
                var systemTbPubItems = await HisDbContext.SystemTbPubItems.Where(w => w.ItemCategory != 13 && w.ItemCategory != 14 && w.ItemCategory != 15 && w.ItemCode.ToString() == value || (w.ItemName != null && w.ItemName.Contains(value))).ToListAsync();
                SelectHisData = new ObservableCollection<SystemTbPubItem>(systemTbPubItems);
            }
        }

        [RelayCommand]
        private void OnInsurPageFirst(object param)
        {
            InsurCurrentPage = 1;
            CalculatePage();
        }

        [RelayCommand]
        private void OnInsurPageUp(object param)
        {
            if (InsurCurrentPage > 1)
                InsurCurrentPage--;
            CalculatePage();
        }

        [RelayCommand]
        private void OnInsurPageDown(object param)
        {
            if (InsurCurrentPage < InsurPageCount)
                InsurCurrentPage++;
            CalculatePage();
        }

        [RelayCommand]
        private void OnInsurPageLast(object param)
        {
            if (InsurCurrentPage < InsurPageCount)
                InsurCurrentPage = InsurPageCount;
            CalculatePage();
        }

        [RelayCommand]
        private void OnHisPageFirst(object param)
        {
            HisCurrentPage = 1;
            CalculatePage();
        }

        [RelayCommand]
        private void OnHisPageUp(object param)
        {
            if (HisCurrentPage > 1)
                HisCurrentPage--;
            CalculatePage();
        }

        [RelayCommand]
        private void OnHisPageDown(object param)
        {
            if (HisCurrentPage < HisPageCount)
                HisCurrentPage++;
            CalculatePage();
        }

        [RelayCommand]
        private void OnHisPageLast(object param)
        {
            if (HisCurrentPage < HisPageCount)
                HisCurrentPage = HisPageCount;
            CalculatePage();
        }
        [RelayCommand]
        private async void OnCorresponding(object param)
        {
            if (SelectedHisData == null)
            {
                SnackbarService.Show(
                        "警告!",
                        $"请选择HIS数据",
                        ControlAppearance.Danger,
                        new SymbolIcon(SymbolRegular.Fluent24),
                        TimeSpan.FromSeconds(30)
                    );
                return;
            }
            if (!string.IsNullOrWhiteSpace(SelectedHisData.InsurGsCode))
            {
                SnackbarService.Show(
                        "警告!",
                        $"当前项目已对照，请勿重复对照",
                        ControlAppearance.Danger,
                        new SymbolIcon(SymbolRegular.Fluent24),
                        TimeSpan.FromSeconds(30)
                    );
                return;
            }
            if (SelectedInsurData == null)
            {
                SnackbarService.Show(
                        "警告!",
                        $"请选择医保数据",
                        ControlAppearance.Danger,
                        new SymbolIcon(SymbolRegular.Fluent24),
                        TimeSpan.FromSeconds(30)
                    );
                return;
            }
            var pubItem = await HisDbContext.SystemTbPubItems.FindAsync(SelectedHisData.GlobalId);
            if (pubItem == null || !string.IsNullOrWhiteSpace(pubItem.InsurGsCode))
            {
                return;
            }
            if (CatalogueType == "01")
            {
                var drug = SelectedInsurData as InsurWorkInjuryCatalogueDrug;
                pubItem.InsurGsCode = drug.DrugCode;
            }
            else if (CatalogueType == "02")
            {
                var treatmentItem = SelectedInsurData as InsurWorkInjuryCatalogueTreatmentItem;
                pubItem.InsurGsCode = treatmentItem.ItemCode;
            }
            HisDbContext.SystemTbPubItems.Update(pubItem);
            await HisDbContext.SaveChangesAsync();
            SnackbarService.Show(
                        "提示!",
                        $"对照成功",
                        ControlAppearance.Success,
                        new SymbolIcon(SymbolRegular.Fluent24),
                        TimeSpan.FromSeconds(30)
                    );
            if (!QueryAll)
                SelectHisData.Remove(SelectedHisData);
        }

        [RelayCommand]
        private async void OnUnCorresponding(object param)
        {
            if (SelectedHisData == null)
            {
                SnackbarService.Show(
                        "警告!",
                        $"请选择HIS数据",
                        ControlAppearance.Danger,
                        new SymbolIcon(SymbolRegular.Fluent24),
                        TimeSpan.FromSeconds(30)
                    );
                return;
            }
            var pubItem = await HisDbContext.SystemTbPubItems.FindAsync(SelectedHisData.GlobalId);
            pubItem.InsurGsCode = null;
            HisDbContext.SystemTbPubItems.Update(pubItem);
            await HisDbContext.SaveChangesAsync();
            SnackbarService.Show(
                        "提示!",
                        $"取消对照成功",
                        ControlAppearance.Success,
                        new SymbolIcon(SymbolRegular.Fluent24),
                        TimeSpan.FromSeconds(30)
                    );
        }
        [RelayCommand]
        private async void OnInsertInsurCode(object param)
        {
            if (SelectedHisData == null)
            {
                SnackbarService.Show(
                        "警告!",
                        $"请选择HIS数据",
                        ControlAppearance.Danger,
                        new SymbolIcon(SymbolRegular.Fluent24),
                        TimeSpan.FromSeconds(30)
                    );
                return;
            }
            if (!string.IsNullOrWhiteSpace(SelectedHisData.InsurGsCode))
            {
                SnackbarService.Show(
                        "警告!",
                        $"当前项目已对照，请勿重复对照",
                        ControlAppearance.Danger,
                        new SymbolIcon(SymbolRegular.Fluent24),
                        TimeSpan.FromSeconds(30)
                    );
                return;
            }
            ContentDialogResult result = await ContentDialogService.ShowSimpleDialogAsync(
            new SimpleContentDialogCreateOptions()
            {
                Title = "请输入医保编码?",
                Content = param,
                PrimaryButtonText = "对照",
                CloseButtonText = "取消",
            }
            );
            if (result != ContentDialogResult.Primary)
                return;
            TextBox textBox = param as TextBox;
            if (string.IsNullOrWhiteSpace(textBox.Text))
            {
                SnackbarService.Show(
                        "警告!",
                        $"请输入医保编码",
                        ControlAppearance.Danger,
                        new SymbolIcon(SymbolRegular.Fluent24),
                        TimeSpan.FromSeconds(30)
                    );
                return;
            }
            var pubItem = await HisDbContext.SystemTbPubItems.FindAsync(SelectedHisData.GlobalId);
            if (pubItem == null || !string.IsNullOrWhiteSpace(pubItem.InsurGsCode))
            {
                return;
            }
            pubItem.InsurGsCode = textBox.Text;
            HisDbContext.SystemTbPubItems.Update(pubItem);
            await HisDbContext.SaveChangesAsync();
            SnackbarService.Show(
                        "提示!",
                        $"对照成功",
                        ControlAppearance.Success,
                        new SymbolIcon(SymbolRegular.Fluent24),
                        TimeSpan.FromSeconds(30)
                    );
            if (!QueryAll)
                SelectHisData.Remove(SelectedHisData);
        }
        [RelayCommand]
        private void OnQueryDetails(object param)
        {
            //HisItemDetailsDict = new Dictionary<string, string>
            //{
            //    {"项目名称",SelectedHisData.ItemName },
            //    {"标准名",SelectedHisData.ItemName },
            //    {"通用名",SelectedHisData.CommonName },
            //    {"输入码1",SelectedHisData.InputCode1 },
            //    {"输入码2",SelectedHisData.InputCode2 },
            //    {"输入码3",SelectedHisData.InputCode3 },
            //    {"通用拼音码",SelectedHisData.PyCode },
            //    {"通用五笔码",SelectedHisData.WbCode },
            //    {"收费大类",SelectedHisData.ItemCategory.ToString() },
            //    {"二级类别",SelectedHisData.ChildItemCategory},
            //    {"门诊包装单位",SelectedHisData.ChildItemCategory},
            //    {"住院包装单位",SelectedHisData.ChildItemCategory},
            //    {"住院包装单位",SelectedHisData.ChildItemCategory},

            //};
            HisItemDetailsDict = ExecuteStoredProcedure(HisDbContext.Database.GetConnectionString(), "USP_GSINSUR_GETPubItem", SelectedHisData.GlobalId.ToString());
            DetailsVisibility = Visibility.Visible;
        }
        [RelayCommand]
        private void OnCloseDetails(object prama)
        {
            DetailsVisibility = Visibility.Collapsed;
        }

        static Dictionary<string, string> ExecuteStoredProcedure(string connectionString, string storedProcedureName,string paramValue)
        {
            var result = new Dictionary<string, string>();

            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                using (SqlCommand command = new SqlCommand(storedProcedureName, connection))
                {
                    command.CommandType = CommandType.StoredProcedure;

                    // 添加参数
                    command.Parameters.AddWithValue("@itemId", paramValue);

                    connection.Open();

                    using (SqlDataReader reader = command.ExecuteReader())
                    {
                        if (reader.Read()) // 只读取第一行数据
                        {
                            for (int i = 0; i < reader.FieldCount; i++)
                            {
                                var key = reader.GetName(i); // 获取列名作为key
                                var value = reader[i]?.ToString(); // 获取对应列的值作为value

                                if (!result.ContainsKey(key))
                                {
                                    result.Add(key, value);
                                }
                            }
                        }
                    }
                }
            }

            // 返回结果
            return result;
        }

        private void CalculatePage()
        {
            if (_allHisData != null)
            {
                HisPageCount = _allHisData.Count() / PageSize + (_allHisData.Count() % PageSize > 0 ? 1 : 0);
                if (HisCurrentPage > 1)
                    HisPageUpIsEnabled = true;
                else
                    HisPageUpIsEnabled = false;
                if (HisCurrentPage < HisPageCount)
                    HisPageDownIsEnabled = true;
                else
                    HisPageDownIsEnabled = false;
                var pubItems = _allHisData.Take(this.HisCurrentPage * this.PageSize).Skip((this.HisCurrentPage - 1) * this.PageSize).ToList();
                if (pubItems != null)
                {
                    SelectHisData = new ObservableCollection<SystemTbPubItem>(pubItems);
                }
            }
            if (_allInsurData != null)
            {
                InsurPageCount = _allInsurData.Count() / PageSize + (_allInsurData.Count() % PageSize > 0 ? 1 : 0);
                if (InsurCurrentPage > 1)
                    InsurPageUpIsEnabled = true;
                else
                    InsurPageUpIsEnabled = false;
                if (InsurCurrentPage < InsurPageCount)
                    InsurPageDownIsEnabled = true;
                else
                    InsurPageDownIsEnabled = false;
                var list = _allInsurData.Take(this.InsurCurrentPage * this.PageSize).Skip((this.InsurCurrentPage - 1) * this.PageSize).ToList();
                if (list != null)
                {
                    SelectInsurData = new ObservableCollection<object>(list);
                }
            }
        }

        private void CalculatePageHis()
        {
            if (_allHisData != null)
            {
                HisPageCount = _allHisData.Count() / PageSize + (_allHisData.Count() % PageSize > 0 ? 1 : 0);
                if (HisCurrentPage > 1)
                    HisPageUpIsEnabled = true;
                else
                    HisPageUpIsEnabled = false;
                if (HisCurrentPage < HisPageCount)
                    HisPageDownIsEnabled = true;
                else
                    HisPageDownIsEnabled = false;
                var pubItems = _allHisData.Take(this.HisCurrentPage * this.PageSize).Skip((this.HisCurrentPage - 1) * this.PageSize).ToList();
                if (pubItems != null)
                {
                    SelectHisData = new ObservableCollection<SystemTbPubItem>(pubItems);
                }
            }
        }
        private void CalculatePageInsur()
        {
            if (_allInsurData != null)
            {
                InsurPageCount = _allInsurData.Count() / PageSize + (_allInsurData.Count() % PageSize > 0 ? 1 : 0);
                if (InsurCurrentPage > 1)
                    InsurPageUpIsEnabled = true;
                else
                    InsurPageUpIsEnabled = false;
                if (InsurCurrentPage < InsurPageCount)
                    InsurPageDownIsEnabled = true;
                else
                    InsurPageDownIsEnabled = false;
                var list = _allInsurData.Take(this.InsurCurrentPage * this.PageSize).Skip((this.InsurCurrentPage - 1) * this.PageSize).ToList();
                if (list != null)
                {
                    SelectInsurData = new ObservableCollection<object>(list);
                }
            }
        }
    }
}
